#include "src/add/add.h"
#include "src/utils/utils.h"

#define M 1024
#define K 1024
#define BLOCKSIZE 32
// #define INFER_TYPE uint8_t
// #define INFER_TYPE float
#define INFER_TYPE  half


int main(){
    int m = M;
    int k = K;
    int blocksize = BLOCKSIZE;
    
    
    // using DATAT=uint8_t;
    using DATAT=INFER_TYPE;

    DATAT* ha;
    DATAT* hb;
    DATAT* hc;
    DATAT* hc_;
    DATAT* da;
    DATAT* db;
    DATAT* dc;
    //为左矩阵分配host内存，初始化数据，分配device内存,将host数据拷贝到device上
    ha = (DATAT*)malloc(m*k*sizeof(DATAT));
    ptr_data_init<DATAT>(ha,m*k);
    cudaMalloc((void**)&da,m*k*sizeof(DATAT));
    cudaMemcpy(da,ha,m*k*sizeof(DATAT),cudaMemcpyHostToDevice);
    //为右矩阵分配host内存，初始化数据，分配device内存,将host数据拷贝到device上
    hb = (DATAT*)malloc(m*k*sizeof(DATAT));
    ptr_data_init<DATAT>(hb,m*k);
    cudaMalloc((void**)&db,m*k*sizeof(DATAT));
    cudaMemcpy(db,hb,m*k*sizeof(DATAT),cudaMemcpyHostToDevice);
    //为结果矩阵分配host内存，为结果矩阵分配device内存
    hc = (DATAT*)malloc(m*k*sizeof(DATAT));
    cudaMalloc((void**)&dc,m*k*sizeof(DATAT));
    launch_matrix_add<DATAT>(da,db,dc,m,k,blocksize,m*k);
    cudaMemcpy(hc,dc,m*k*sizeof(DATAT),cudaMemcpyDeviceToHost);
    hc_ = (DATAT*)malloc(m*k*sizeof(DATAT));
    CPU_Matrix_add(ha,hb,hc_,m,k);
    bool success = check_cpu_cuda_cal_result<DATAT>(hc_,hc,m,k);
    if(success){
        printf("%s CPU && CUDA get the same result!\n",typeid(DATAT).name());
    }
    free(ha);
    free(hb);
    free(hc);
    cudaFree(da);
    cudaFree(db);
    cudaFree(dc);
    return 0;

}